package com.xhwl.centiotdata.suppliersystem.fushi;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xhwl.centiotdata.pojo.constant.FuShiConstant;
import com.xhwl.centiotdata.pojo.dto.device.DeviceIntegrationConfigDTO;
import com.xhwl.centiotdata.pojo.dto.fushi.DeviceFuShiDTO;
import com.xhwl.centiotdata.pojo.dto.fushi.PedestrianPicFuShiDTO;
import com.xhwl.centiotdata.pojo.dto.fushi.PedestrianRecordFuShiDTO;
import com.xhwl.centiotdata.pojo.dto.fushi.UserFuShiDTO;
import com.xhwl.centiotdata.pojo.dto.pedestrian.PedestrianIntegrationConfigDTO;
import com.xhwl.centiotdata.service.cent.IAccountCentService;
import com.xhwl.centiotdata.service.cent.IAuthAccountCentService;
import com.xhwl.centiotdata.utils.RedisUtils;
import com.xhwl.common.dto.auth.PedestrianAuthDTO;
import com.xhwl.common.dto.cent.pedes.OpenDoorRecordDTO;
import com.xhwl.common.enums.AccessTypeEnum;
import com.xhwl.common.enums.DirectionEnum;
import com.xhwl.common.enums.SourceTypeEnum;
import com.xhwl.common.exception.BusinessException;
import com.xhwl.common.pojo.cent.auth.AuthAccountMapping;
import com.xhwl.common.pojo.cent.sdata.Account;
import com.xhwl.common.query.cent.sdata.AccountQuery;
import com.xhwl.common.utils.ChkUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author: yanyixiong
 * @Description:
 * @Date: create in 14:39 2023/4/21
 */
@Slf4j
@Service
public class PedestrianFuShiHandler {

    @Autowired
    private IAccountCentService accountCentService;
    @Autowired
    private GeneralFuShiHandler generalFuShiHandler;
    @Autowired
    private DeviceFuShiHandler deviceFuShiHandler;
    @Autowired
    private IAuthAccountCentService authAccountCentService;
    @Autowired
    private RedisUtils redisUtils;


    public AuthAccountMapping createUser(PedestrianIntegrationConfigDTO configDTO, PedestrianAuthDTO pedestrianAuthDTO) {

        Integer accountId = pedestrianAuthDTO.getSourceId();
        AccountQuery accountQuery = new AccountQuery();
        accountQuery.setId(accountId);
        Account account = accountCentService.getAccount(null, accountQuery);
        if(account == null){
            throw new BusinessException("不存在该人员！");
        }

        String organizationId = queryOrganization(configDTO);
        if(StringUtils.isBlank(organizationId)){
            organizationId = addOrganization(configDTO);
        }

        Date date = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        String dateStr = simpleDateFormat.format(date);
        String rid = generalFuShiHandler.generaRid();
        UserFuShiDTO userFuShiDTO = UserFuShiDTO.builder()
                .Birthday(dateStr)
                .OrganizationId(organizationId)
                .OwnerCode("")
                .OwnerParentCode("")
                .RollDate(date)
                .Rid(rid)
                .StaffName(account.getName())
                .StaffNo(generalFuShiHandler.generaStaffNo(configDTO.getProjectId(), accountId))
                .build();

        String openCode = addUser(userFuShiDTO, configDTO);

        AuthAccountMapping authAccountMapping = new AuthAccountMapping();
        authAccountMapping.setOpenId(rid);
        authAccountMapping.setOpenCode(openCode);
        authAccountMapping.setAccountId(accountId);
        authAccountMapping.setProductId(configDTO.getProductId());
        authAccountMapping.setProjectId(configDTO.getProjectId());
        authAccountCentService.save(configDTO.getProjectId(), pedestrianAuthDTO.getSourceId(),rid, openCode ,configDTO.getProductId());
        return authAccountMapping;

    }

    /**
     * 传入格式：
     * {
     * 	"StaffNo": "0889086B-BA06-4E0A-9A4B-A62B01CE1FF1",
     * 	"SroreType": 1,
     * 	"BinaryData": null,
     * 	"FileData":"http://127.0.0.1:60001/HeadPic/20180711/19/6393400467.jpg",
     * 	"Gid": "1C1020C9-66FA-4489-B3AE-35872F51CF5C",
     * 	"Rid": "5fe60666-88ae-4951-9595-785d15671fcf"
     * }
     * 结果示例：
     * {
     * "IsSucess": true,
     * "IsError": false,
     * "Code": 0,
     * "RecordAffected": 1,
     * "Describe": "sample string 2"
     * }
     * @param faceUrl
     * @param configDTO
     */
    public void addFace(String openId, String faceUrl, PedestrianIntegrationConfigDTO configDTO) {
        Map<String, Object> params = new HashMap<>();
        params.put("StaffNo", openId);
        params.put("SroreType", 1);
        params.put("fileData", faceUrl);
        params.put("Rid", generalFuShiHandler.generaRid());
        JSONObject result = generalFuShiHandler.post(FuShiConstant.ADD_FACE, params, configDTO.getIpAndPort(), configDTO.getTagId());
        Boolean isSucess = result.getBoolean("IsSucess");
        if(!isSucess){
            log.error("项目{}供应商{}新增人员失败，返回{}",configDTO.getProjectId(), configDTO.getProductId(), JSONObject.toJSONString(result));
        }

    }

    /**
     * 修改人脸
     * @param openId
     * @param faceUrl
     * @param configDTO
     */
    public void updateFace(String openId, String faceUrl, PedestrianIntegrationConfigDTO configDTO) {
        Map<String, Object> params = new HashMap<>();
        params.put("id", openId);
        //对应人员的Rid
        params.put("StaffNo", openId);
        params.put("SroreType", 1);
        params.put("fileData", faceUrl);
        params.put("Rid", generalFuShiHandler.generaRid());
        JSONObject result = generalFuShiHandler.put(FuShiConstant.UPDATE_FACE, params, configDTO.getIpAndPort(), configDTO.getTagId());
        Boolean isSucess = result.getBoolean("IsSucess");
        if(!isSucess){
            log.error("项目{}供应商{}新增人员失败，返回{}",configDTO.getProjectId(), configDTO.getProductId(), JSONObject.toJSONString(result));
        }
    }

    public void deleteFace(String openId, PedestrianIntegrationConfigDTO configDTO) {
        Map<String, Object> params = new HashMap<>();
        params.put("StaffNo", openId);
        JSONObject result = generalFuShiHandler.post(FuShiConstant.DELETE_FACE, params, configDTO.getIpAndPort(), configDTO.getTagId());
        Boolean isSucess = result.getBoolean("IsSucess");
        if(!isSucess){
            log.error("项目{}供应商{}删除人员失败，返回{}",configDTO.getProjectId(), configDTO.getProductId(), JSONObject.toJSONString(result));
        }
    }

    /**
     * 通知设备拉取人脸图片
     * @param openId
     * @param configDTO
     */
    public void notify(String openId,  PedestrianIntegrationConfigDTO configDTO) {
        Map<String, Object> params = new HashMap<>();
        params.put("rids", Collections.singletonList(openId));
        //对应人员的Rid
        params.put("messageType", 8);
        JSONObject result = generalFuShiHandler.post(FuShiConstant.QUEUE_MESSAGE, params, configDTO.getIpAndPort(), configDTO.getTagId());
        log.info("项目{}供应商{}通知设备拉取人脸图片，返回{}",configDTO.getProjectId(), configDTO.getProductId(), JSONObject.toJSONString(result));
    }

    /**
     * {
     *     "IsSucess":true,
     *     "IsError":false,
     *     "Code":0,
     *     "RecordAffected":0,
     *     "Describe":"1"
     * }
     * @param userFuShiDTO
     * @param configDTO
     */
    private String addUser(UserFuShiDTO userFuShiDTO, PedestrianIntegrationConfigDTO configDTO){
        Map<String,Object> params = JSONObject.parseObject(JSONObject.toJSONString(userFuShiDTO), Map.class);
        JSONObject result = generalFuShiHandler.post(FuShiConstant.ADD_USER, params, configDTO.getIpAndPort(), configDTO.getTagId());
        if(result.getBoolean("IsSucess")){
            return result.getString("Describe");
        }else {
            log.error("项目{}供应商{}创建人员失败，原因是{}",configDTO.getProjectId(), configDTO.getProductId(), JSONObject.toJSONString(result));
            throw new BusinessException(result.getString("Describe"));
        }
    }

    private UserFuShiDTO queryUser(String openId, PedestrianIntegrationConfigDTO configDTO){
        HashMap<String, Object> params = new HashMap<>();
        params.put("CurrentPage", 1);
        params.put("pageSize", 1);
        params.put("OrderBy","ID");
        params.put("OrderType","true");
        params.put("where"," Rid = '"+ openId +"' ");
        JSONObject result = generalFuShiHandler.post(FuShiConstant.QUERY_USER, params, configDTO.getIpAndPort(), configDTO.getTagId());
        JSONObject state = result.getJSONObject("State");
        if(state.getBoolean("IsSucess")){
            String recordStr = result.getString("Records");
            if (StringUtils.isEmpty(recordStr) || "null".equals(recordStr)) {
                log.error("post path:{};params:{};pageData is null!", FuShiConstant.QUERY_USER, JSON.toJSONString(params));
                return null;
            }
            List<UserFuShiDTO> userFuShiDTOS = JSONObject.parseArray(recordStr, UserFuShiDTO.class);
            if(CollectionUtils.isEmpty(userFuShiDTOS)){
                return null;
            }
            return userFuShiDTOS.get(0);
        }else {
            log.error("项目{}供应商{}查询人员失败，原因是{}",configDTO.getProjectId(), configDTO.getProductId(), JSONObject.toJSONString(result));
            return null;
        }
    }


    private String queryOrganization(PedestrianIntegrationConfigDTO configDTO){
        HashMap<String, Object> params = new HashMap<>();
        params.put("CurrentPage",1);
        params.put("PageSize",1);
        params.put("where"," Name = '"+ FuShiConstant.ORGANIZATION_NAME +"' ");
        JSONObject result = generalFuShiHandler.post(FuShiConstant.QUERY_ORGANIZATION, params,
                configDTO.getIpAndPort(), configDTO.getTagId());
        JSONObject state = result.getJSONObject("State");
        if(state.getBoolean("IsSucess")){
            JSONArray jsonArray = result.getJSONArray("Records");
            if(jsonArray == null || jsonArray.isEmpty()){
                return null;
            }
            return jsonArray.getJSONObject(0).getString("Rid");
        }
        return null;
    }

    /**
     * {
     *     "ID":0,
     *     "Name":"一级",
     *     "ParentId":"-1",
     *     "Remark":"remark 一级",
     *     "Gid":"CA38CE04-A164-4487-843E-A55CEEBA6783",
     *     "Rid":"c0e906de-2e34-4bc6-b04b-75cd09e01baf"
     * }
     *
     * @param configDTO
     * @return
     */
    private String addOrganization(PedestrianIntegrationConfigDTO configDTO){
        String rid = generalFuShiHandler.generaRid();
        HashMap<String, Object> params = new HashMap<>();
        params.put("Name", FuShiConstant.ORGANIZATION_NAME);
        params.put("Rid", rid);
        JSONObject result = generalFuShiHandler.post(FuShiConstant.ADD_ORGANIZATION, params,
                configDTO.getIpAndPort(), configDTO.getTagId());

        if(result.getBoolean("IsSucess")){
            return rid;
        }else {
            log.error("项目{}供应商{}创建组织机构失败，原因是{}",configDTO.getProjectId(), configDTO.getProductId(), JSONObject.toJSONString(result));
            throw new BusinessException(result.getString("Describe"));
        }
    }

    private boolean existAuth(PedestrianAuthDTO pedestrianAuthDTO){
        String key = String.format(FuShiConstant.ALREADY_AUTH,pedestrianAuthDTO.getProjectId(), pedestrianAuthDTO.getSourceId());
        return redisUtils.exists(key);
    }

    /**
     * 新增授权
     * @param authType 授权类型 1 卡 2 人脸
     */
    public void saveAuth(PedestrianIntegrationConfigDTO configDTO, PedestrianAuthDTO pedestrianAuthDTO, Integer authType) {
        if(existAuth(pedestrianAuthDTO)){
            updateAuth(configDTO,pedestrianAuthDTO,authType);
            return;
        }
        List<String> thirdDeviceIdList = pedestrianAuthDTO.getThirdDeviceIdList();
        if(CollectionUtils.isEmpty(thirdDeviceIdList)){
            log.info("没有要授权的第三方设备！！");
            return;
        }
        String userOpenId = pedestrianAuthDTO.getUserOpenId();
        UserFuShiDTO userFuShiDTO = this.queryUser(userOpenId, configDTO);
        if(userFuShiDTO == null){
            AuthAccountMapping authAccountMapping = createUser(configDTO, pedestrianAuthDTO);
            userOpenId = authAccountMapping.getOpenId();
            userFuShiDTO = this.queryUser(userOpenId, configDTO);
        }
        assert userFuShiDTO != null;

        Map<String, Object> authParam = buildAuthParam(userFuShiDTO, authType);
        authParam.put("DoorIssue", buildDoorIssue(configDTO, pedestrianAuthDTO,userFuShiDTO,authType,true));

        JSONObject result = generalFuShiHandler.post(FuShiConstant.ADD_AUTH, authParam,
                configDTO.getIpAndPort(), configDTO.getTagId());
        JSONObject state = result.getJSONObject("State");
        if(state.getBoolean("IsSucess")){
            JSONObject model = result.getJSONObject("Model");
            if(model.getBoolean("Result")){
                log.info("授权成功！");
                String key = String.format(FuShiConstant.ALREADY_AUTH,pedestrianAuthDTO.getProjectId(), pedestrianAuthDTO.getSourceId());
                redisUtils.set(key,1);
            }else {
                log.error("授权失败！参数 {}, 返回： {}",JSONObject.toJSONString(authParam), JSONObject.toJSONString(model));
            }
        }else {
            log.error("授权失败！参数 {}, 返回： {}",JSONObject.toJSONString(authParam), JSONObject.toJSONString(result));
        }
    }

    private Map<String, Object> buildDelAuthParam(PedestrianIntegrationConfigDTO configDTO, UserFuShiDTO userFuShiDTO){
        Map<String, Object> authParam = new HashMap<>();
        authParam.put("SubSystems", Collections.singletonList(2));
        authParam.put("DepositMoney", 0.00);
        authParam.put("VmsOperMoney", 0.00);
        authParam.put("CmsOperMoney", 0.00);
        Integer identNumber = userFuShiDTO.getIdentNumber();
        String IcNumber = String.format("%08X", identNumber);
        authParam.put("Token", IcNumber );
        authParam.put("TokenType", 1);
        authParam.put("IsExistCard", true);
        authParam.put("UseModel", 1);
        authParam.put("TokenOper", 12);
        authParam.put("OperNo", 0.00);
        authParam.put("OperName", 1);
        authParam.put("Redate", new Date());
        authParam.put("OldAccountBlace", 0.00);
        authParam.put("ID", 0);
        String rid = generalFuShiHandler.generaRid();
        authParam.put("Rid", rid);
        authParam.put("ProjectGids",Collections.singletonList(configDTO.getTagId()));
        authParam.put("IsLegal",true);
        return authParam;
    }

    private Map<String, Object> buildAuthParam(UserFuShiDTO userFuShiDTO, Integer authType){
        assert userFuShiDTO != null;
        Map<String, Object> authParam = new HashMap<>();
        Integer identNumber = userFuShiDTO.getIdentNumber();
        String IcNumber = String.format("%08X", identNumber);
        authParam.put("IcNumber", IcNumber);
        authParam.put("IdNumber", IcNumber);
        if(authType == 1){
            authParam.put("TokenType", 1);
        }else if(authType == 2){
            authParam.put("TokenType",5);
        }
        authParam.put("Deposit", 0);
        authParam.put("IsWrite", false);
        authParam.put("StaffNo", userFuShiDTO.getStaffNo());
        authParam.put("StaffName", userFuShiDTO.getStaffName());
        authParam.put("OrginazitionId", userFuShiDTO.getOrganizationId());
        authParam.put("OperNo",userFuShiDTO.getStaffNo());
        authParam.put("OperName", userFuShiDTO.getStaffName());
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        authParam.put("Redate", sdf.format(new Date()));
        authParam.put("Rid", generalFuShiHandler.generaRid());
        authParam.put("ID", 0);
        authParam.put("IsLegal", true);
        return authParam;
    }


    private Map<String, Object> buildDoorIssue(PedestrianIntegrationConfigDTO configDTO, PedestrianAuthDTO pedestrianAuthDTO,
                                               UserFuShiDTO userFuShiDTO, Integer authType , Boolean save){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Integer identNumber = userFuShiDTO.getIdentNumber();
        String IcNumber = String.format("%08X", identNumber);
        Map<String, Object> doorIssue = new HashMap<>();
        //登记时填写：register=1,//发卡/批量发卡/登记
        //改写：modify=2,//改写/批量改写
        //注销（删除）：unregister=12,//退卡
        if(save){
            doorIssue.put("TokenOper", 1);
        }else {
            doorIssue.put("TokenOper", 2);
        }
        doorIssue.put("TokenId", IcNumber);
        doorIssue.put("SerialNo", IcNumber);
        doorIssue.put("StaffNo", userFuShiDTO.getStaffNo());
        doorIssue.put("StaffName", userFuShiDTO.getStaffName());
        doorIssue.put("OrginazitionId", userFuShiDTO.getOrganizationId());
        doorIssue.put("Tcm", configDTO.getToken());
        doorIssue.put("Stcm", "");
        doorIssue.put("BeginDate", sdf.format(pedestrianAuthDTO.getValidStartTime()));
        doorIssue.put("EndDate", sdf.format(pedestrianAuthDTO.getValidEndTime()));
        doorIssue.put("IcStartTimeL1", "00:00");
        doorIssue.put("IcStartTimeR1", "23:59");
        doorIssue.put("IcStartTimeL2", "00:00");
        doorIssue.put("IcStartTimeR2", "00:00");
        doorIssue.put("IcStartTimeL3", "00:00");
        doorIssue.put("IcStartTimeR3", "00:00");
        doorIssue.put("IcStartTimeL4", "00:00");
        doorIssue.put("IcStartTimeR4", "00:00");
        doorIssue.put("EMUseMaxCount", 65535);
        doorIssue.put("FGroupNo", 0);
        doorIssue.put("FAntiPassback", 0);
        doorIssue.put("CarPass", "FFFFFF");


        List<String> thirdDeviceIdList = pedestrianAuthDTO.getThirdDeviceIdList();
        if(!CollectionUtils.isEmpty(thirdDeviceIdList)){
            String where = "DevNo in (" +  thirdDeviceIdList.stream().map(id -> "'"+id+"'").collect(Collectors.joining(",")) +")";
            DeviceIntegrationConfigDTO deviceConfigDTO = new DeviceIntegrationConfigDTO();
            deviceConfigDTO.setProductId(configDTO.getProductId());
            deviceConfigDTO.setIpAndPort(configDTO.getIpAndPort());
            deviceConfigDTO.setProjectId(configDTO.getProjectId());
            deviceConfigDTO.setTagId(configDTO.getTagId());
            List<DeviceFuShiDTO> deviceFuShiDTOList = deviceFuShiHandler.pullPedestrianDevice(deviceConfigDTO, where);
            List<Map<String, Object>> devices = deviceFuShiDTOList.stream().map(deviceFuShiDTO -> {
                Map<String, Object> map = new HashMap<>();
                map.put("TokenId", IcNumber);
                map.put("DevTypeCode", deviceFuShiDTO.getDevTypeCode());
                map.put("CollectCode", deviceFuShiDTO.getCollectCode());
                map.put("DevNo", deviceFuShiDTO.getDevNo());
                map.put("DevName", deviceFuShiDTO.getDevName());

                map.put("D1Valid", 0);
                map.put("D1Grant", 1);
                map.put("D1OpenMode", 1);
                map.put("D1ReadName", null);
                map.put("D2Valid", 0);
                map.put("D2Grant", 0);
                map.put("D2OpenMode", 0);
                map.put("D2ReadName", null);
                map.put("D3Valid", 0);
                map.put("D3Grant", 0);
                map.put("D3OpenMode", 0);
                map.put("D3ReadName", null);
                map.put("D4Valid", 0);
                map.put("D4Grant", 0);
                map.put("D4OpenMode", 0);
                map.put("D4ReadName", null);
                map.put("D5Valid", 0);
                map.put("D5Grant", 0);
                map.put("D5OpenMode", 0);
                map.put("D5ReadName", null);
                map.put("D6Valid", 0);
                map.put("D6Grant", 0);
                map.put("D6OpenMode", 0);
                map.put("D6ReadName", null);
                map.put("D7Valid", 0);
                map.put("D7Grant", 0);
                map.put("D7OpenMode", 0);
                map.put("D7ReadName", null);
                map.put("D8Valid", 0);
                map.put("D8Grant", 0);
                map.put("D8OpenMode", 0);
                map.put("D8ReadName", null);

                map.put("Gid", deviceConfigDTO.getTagId());
                map.put("Rid", generalFuShiHandler.generaRid());
                return map;
            }).collect(Collectors.toList());
            doorIssue.put("DoorGrant", devices);
        }

        doorIssue.put("AuthDevice", new ArrayList<>());
        doorIssue.put("EmGrant", new ArrayList<>());

        doorIssue.put("Token", IcNumber);
        if(authType == 1){
            doorIssue.put("IsExistCard", true);
            doorIssue.put("TokenType", 1);
        }else if(authType == 2){
            doorIssue.put("IsExistCard", false);
            doorIssue.put("TokenType", 5);
        }
        doorIssue.put("UseModel", 1);
        doorIssue.put("OperNo", userFuShiDTO.getStaffNo());
        doorIssue.put("OperName", userFuShiDTO.getStaffName());
        doorIssue.put("Redate", sdf.format(new Date()));
        String rid = generalFuShiHandler.generaRid();
        doorIssue.put("Rid", rid);
        doorIssue.put("Gid", configDTO.getTagId());
        doorIssue.put("ProjectGids", Collections.singletonList(configDTO.getTagId()));
        doorIssue.put("IsLegal", true);
        return doorIssue;
    }

    /**
     * 删除授权
     */
    public void deleteAuth(PedestrianIntegrationConfigDTO configDTO, PedestrianAuthDTO pedestrianAuthDTO) {
        String userOpenId = pedestrianAuthDTO.getUserOpenId();
        UserFuShiDTO userFuShiDTO = this.queryUser(userOpenId, configDTO);
        if(userFuShiDTO == null){
            log.warn("删除授权，富士系统中没有该人员！");
            return;
        }
        Map<String, Object> delAuthParam = buildDelAuthParam(configDTO, userFuShiDTO);
        JSONObject result = generalFuShiHandler.post(FuShiConstant.DELETE_AUTH, delAuthParam,
                configDTO.getIpAndPort(), configDTO.getTagId());
        if(result.getBoolean("IsSucess")){
            log.info("授权删除成功！");
            String key = String.format(FuShiConstant.ALREADY_AUTH,pedestrianAuthDTO.getProjectId(), pedestrianAuthDTO.getSourceId());
            redisUtils.remove(key);
        }else {
            log.error("授权删除失败！参数 {}, 返回： {}",JSONObject.toJSONString(delAuthParam), JSONObject.toJSONString(result));
        }
    }

    /**
     * 修改授权
     * @param authType 授权类型 1 卡 2 人脸
     */
    public void updateAuth(PedestrianIntegrationConfigDTO configDTO, PedestrianAuthDTO pedestrianAuthDTO, Integer authType) {
        if(!existAuth(pedestrianAuthDTO)){
            saveAuth(configDTO,pedestrianAuthDTO,authType);
            return;
        }
        List<String> thirdDeviceIdList = pedestrianAuthDTO.getThirdDeviceIdList();
        if(CollectionUtils.isEmpty(thirdDeviceIdList)){
            log.info("没有要授权的第三方设备！！");
            return;
        }
        String userOpenId = pedestrianAuthDTO.getUserOpenId();
        UserFuShiDTO userFuShiDTO = this.queryUser(userOpenId, configDTO);
        assert userFuShiDTO != null;

        Map<String, Object> authParam = buildAuthParam(userFuShiDTO, authType);
        authParam.put("DoorIssue", buildDoorIssue(configDTO, pedestrianAuthDTO,userFuShiDTO,authType,false));

        JSONObject result = generalFuShiHandler.post(FuShiConstant.ADD_AUTH, authParam,
                configDTO.getIpAndPort(), configDTO.getTagId());
        JSONObject state = result.getJSONObject("State");
        if(state.getBoolean("IsSucess")){
            JSONObject model = result.getJSONObject("Model");
            if(model.getBoolean("Result")){
                log.info("授权修改成功！");
            }else {
                log.error("授权修改失败！参数 {}, 返回： {}",JSONObject.toJSONString(authParam), JSONObject.toJSONString(model));
            }
        }else {
            log.error("授权修改失败！参数 {}, 返回： {}",JSONObject.toJSONString(authParam), JSONObject.toJSONString(result));

        }
    }

    /**
     * 拉取第三方的人行记录
     * @param configDTO
     * @return
     */
    public List<PedestrianRecordFuShiDTO> pullRecord(PedestrianIntegrationConfigDTO configDTO, Integer intervalDays, Date date) {
        if(date == null){
            date = new Date();
        }
        //计算开始时间
        //拉取15秒前的数据
        Date startDate  = new Date(date.getTime() - 15*1000);
        if(intervalDays != null){
            startDate = new Date(date.getTime() + (24*60*60*1000L * intervalDays) - 15*1000L );
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");

        List<PedestrianRecordFuShiDTO> recordFuShiDTOList = new ArrayList<>();
        Integer currentPage = 1;
        String where = " OpenDate >= '"+sdf.format(startDate)+"' and OpenDate < '"+sdf.format(date)+"' ";
        List<PedestrianRecordFuShiDTO> recordList = null;
        do {
            recordList = this.requestRecord(currentPage, where, configDTO);
            if (CollectionUtils.isEmpty(recordList)) {
                break;
            }
            recordFuShiDTOList.addAll(recordList);
            ++currentPage;
        } while (!CollectionUtils.isEmpty(recordList) && recordList.size() == 500);
        return recordFuShiDTOList;
    }

    private List<PedestrianRecordFuShiDTO> requestRecord(Integer currentPage, String where, PedestrianIntegrationConfigDTO configDTO) {
        HashMap<String, Object> params = new HashMap<>();
        params.put("CurrentPage", currentPage);
        params.put("pageSize", 500);
        params.put("OrderBy","ID");
        params.put("OrderType","true");
        params.put("where",where);
        JSONObject result = generalFuShiHandler.post(FuShiConstant.QUERY_RECORD, params,
                configDTO.getIpAndPort(), configDTO.getTagId());
        JSONObject state = result.getJSONObject("State");
        if(state.getBoolean("IsSucess")){
            String recordStr = result.getString("Records");
            if (StringUtils.isEmpty(recordStr)) {
                log.error("post path:{};params:{};pageData is null!", FuShiConstant.QUERY_RECORD, JSON.toJSONString(params));
                return new ArrayList<>();
            }
            List<PedestrianRecordFuShiDTO> recordFuShiDTOList = JSONObject.parseArray(recordStr, PedestrianRecordFuShiDTO.class);
            return recordFuShiDTOList;
        }else {
            log.error("项目{}供应商{}拉取人行记录失败，原因是{}",configDTO.getProjectId(), configDTO.getProductId(), JSONObject.toJSONString(result));
            return new ArrayList<>();
        }
    }



    /**
     * 解析处理人行记录
     * 将第三方的记录处理成中台人行记录格式
     * @param configDTO
     * @param recordFuShiDTOList
     * @return
     */
    public List<OpenDoorRecordDTO> handleRecord(PedestrianIntegrationConfigDTO configDTO, List<PedestrianRecordFuShiDTO> recordFuShiDTOList) {
        if(CollectionUtils.isEmpty(recordFuShiDTOList)){
            return new ArrayList<>();
        }
        List<String> picNoList = recordFuShiDTOList.stream().filter(item->ChkUtil.isNotNull(item.getOpenPicNo()))
                .map(PedestrianRecordFuShiDTO::getOpenPicNo).collect(Collectors.toList());

        List<PedestrianPicFuShiDTO> picFuShiDTOList = queryPic(configDTO, picNoList);
        Map<String, String> picMap = picFuShiDTOList.stream().collect(Collectors.toMap(PedestrianPicFuShiDTO::getOpenPicNo, PedestrianPicFuShiDTO::getPicAddr));

        List<OpenDoorRecordDTO> openDoorRecordDTOList = new ArrayList<>();
        recordFuShiDTOList.forEach(recordFuShiDTO->{
            if(isPedestrianRecord(recordFuShiDTO)){
                OpenDoorRecordDTO openDoorRecordDTO = OpenDoorRecordDTO.builder()
                        .projectId(configDTO.getProjectId())
                        .deviceName(recordFuShiDTO.getDevName())
                        .arrivalTime(recordFuShiDTO.getOpenDate())
                        .openUserId(recordFuShiDTO.getStaffId())//对应人员的Rid
                        .openDeviceId(recordFuShiDTO.getDevNo().toString())
//                    .openUserType(1) //第三方人员类型
                        .sourceType(SourceTypeEnum.USER.type) //业务端来源
                        .direction(handleDirection(recordFuShiDTO.getComeGo()))
                        .type(handleType(recordFuShiDTO.getTokenType()))//出入方式
                        .state((short)1)//状态 成功/失败
                        .pictureUrl(picMap.get(recordFuShiDTO.getOpenPicNo()))
                        .bodyTemperature(recordFuShiDTO.getBodyTemperature())
                        .build();
                openDoorRecordDTOList.add(openDoorRecordDTO);
            }

        });
        return openDoorRecordDTOList;
    }

    public List<PedestrianPicFuShiDTO> queryPic(PedestrianIntegrationConfigDTO configDTO, List<String> picNoList) {
        String where = "'" + picNoList.stream().collect(Collectors.joining("','")) + "'";
        HashMap<String, Object> params = new HashMap<>();
        params.put("CurrentPage", 1);
        params.put("pageSize", 1000);
        params.put("where","OpenPicNo in (" + where + ")");
        JSONObject result = generalFuShiHandler.post(FuShiConstant.QUERY_PIC, params,
                configDTO.getIpAndPort(), configDTO.getTagId());
        JSONObject state = result.getJSONObject("State");
        if(state.getBoolean("IsSucess")){
            String recordStr = result.getString("Records");
            if (StringUtils.isEmpty(recordStr)) {
                log.error("post path:{};params:{};pageData is null!", FuShiConstant.QUERY_PIC, JSON.toJSONString(params));
                return new ArrayList<>();
            }
            List<PedestrianPicFuShiDTO> picFuShiDTOList = JSONObject.parseArray(recordStr, PedestrianPicFuShiDTO.class);
            return picFuShiDTOList;
        }else {
            log.error("项目{}供应商{}查询人行记录图片失败，原因是{}",configDTO.getProjectId(), configDTO.getProductId(), JSONObject.toJSONString(result));
            return new ArrayList<>();
        }
    }


    private boolean isPedestrianRecord(PedestrianRecordFuShiDTO pedestrianRecordFuShiDTO){
        Integer tokenType = pedestrianRecordFuShiDTO.getTokenType();
        if(tokenType == null){
            log.warn("富士门禁出入记录没有出入方式！ {}",JSONObject.toJSONString(pedestrianRecordFuShiDTO));
            return false;
        }
        if( tokenType == 1 || tokenType == 4 || tokenType == 5){
            return true;
        }
        return false;
    }

    /**
     * 处理出入方式
     * @param tokenType
     * @return
     */
    private Short handleType(Integer tokenType) {
        //0 车牌 1 卡片 2 ETC 3纸票 4二维码 5 生物
        if (tokenType == null){
            return AccessTypeEnum.OTHER.getId();
        }
        switch (tokenType){
            case 1:
                return AccessTypeEnum.IC_CARD.getId();
            case 4:
                return AccessTypeEnum.QR_CODE.getId();
            case 5:
                return AccessTypeEnum.FACE.getId();
        }
        return AccessTypeEnum.OTHER.getId();
    }

    /**
     * 处理出入方向
     * @param comeGo
     * @return
     */
    private Short handleDirection(Integer comeGo) {

        if(comeGo == null){
            return DirectionEnum.UNKNOWN.getId();
        }

        switch (comeGo){
            case 0 :
                return DirectionEnum.OUT.getId();
            case 1:
                return DirectionEnum.IN.getId();
        }
        return DirectionEnum.UNKNOWN.getId();
    }


}
